package com.zzl.springboot_mybatis_demo.job;

import com.gitee.yongzhuzl.commonutil.util.date.CalendarUtil;
import com.zzl.springboot_mybatis_demo.entity.order.TbOrder;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

import java.util.*;

/**
 * description: quartz任务的job，用于检测数据库失效订单并将其关闭
 * DisallowConcurrentExecution这个注解标明上个任务没有执行完毕不会执行下个任务
 * @author 朱正磊
 * @date 2020-06-20 21:17:33
 */
@Slf4j
@DisallowConcurrentExecution
public class CancelOrderJob implements Job {

    // 订单有效时间40分钟
    private static final long EFFECTIVE_TIME = 40 * 60 * 1000;

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("失效订单检测任务开始执行!");
        Queue<TbOrder> queue = new LinkedList<>();

        // 在每次启动Job时去数据库查找失效订单，并加入到队列中(从数据库中查询，此处使用假数据)
        List<TbOrder> list = this.getInvalidOrder();
        if (!list.isEmpty()) {
            for (TbOrder o : list) {
                queue.offer(o);
            }
        }

        // 获取队列的头元素,开始检测头订单是否失效
        TbOrder element = queue.peek();
        while (element != null) {
            // 时间差值
            Long diff = this.checkOrder(element);
            if (diff >= EFFECTIVE_TIME) {
                System.out.println("开始关闭订单ID：" + element.getOrderId()
                        + "，下单时间：" + CalendarUtil.dateToString(element.getCreateTime()));
                // 弹出队列
                queue.poll();
                // 取下一个元素
                element = queue.peek();
            } else if (diff < EFFECTIVE_TIME) {
                try {
                    System.out.println("等待检测订单ID：" + element.getOrderId()
                            + "，下单时间：" + CalendarUtil.dateToString(element.getCreateTime())
                            + "，已下单：" + diff / 1000 + "秒");
                    //线程等待
                    Thread.sleep(EFFECTIVE_TIME - diff);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                    log.info("CancelOrderJob.checkOrder定时任务出现问题");
                }
            }
        }

    }

    /**
     * description:  获取订单的下单时间和现在的时间差
     * @author 朱正磊
     * @date 2020-06-20 21:29:56
     * @param order 订单
     * @return 返回订单的下单时间和现在的时间差
     */
    private Long checkOrder(TbOrder order) {
        return System.currentTimeMillis() - order.getCreateTime().getTime();
    }

    /**
     * description: 生产订单假数据用于测试
     * @author 朱正磊
     * @date 2020-06-20 21:25:09
     * @return 返回订单列表
     */
    private List<TbOrder> getInvalidOrder() {
        List<TbOrder> invalidOrderList = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            TbOrder order = new TbOrder();
            order.setOrderId(String.valueOf(i));
            order.setCreateTime(new Date());
            invalidOrderList.add(order);
        }
        return invalidOrderList;
    }

}
